package edu.arizona.bio5.onto.decomposition.persistent.rdf;

import org.coode.owlapi.rdf.model.RDFLiteralNode;
import org.coode.owlapi.rdf.model.RDFNode;
import org.coode.owlapi.rdf.model.RDFResourceNode;
import org.coode.owlapi.rdf.model.RDFTranslator;
import org.openrdf.model.Resource;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.semanticweb.owlapi.model.OWLAxiom;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyManager;

public class OWLAPIToSesameTranslator extends RDFTranslator/*<RDFNode, Resource, Property, Literal>*/ {

	private RepositoryConnection mConnection = null;
	private ValueFactory mValueFactory = null;
	private URI mContext = null;
	private RepositoryException mError = null;
	
	public OWLAPIToSesameTranslator(OWLOntologyManager mgr, OWLOntology ontology, RepositoryConnection conn) {
		super(mgr, ontology, false);
		mConnection = conn;
		mValueFactory = conn.getValueFactory();
	}
	
	void setContext(URI context) {
		mContext = context;
	}

	
	
	@Override
	public void visit(OWLOntology ontology) {
		mError = null;
		super.visit(ontology);
		
		for (OWLAxiom axiom : ontology.getAxioms()) {
			axiom.accept(this);
		}
	}
	
	RepositoryException getError() {
		return mError;
	}

	@Override
	protected void addTriple(RDFResourceNode subj, RDFResourceNode prop, RDFNode obj) {
		
		if (mError != null) return;
		
		try {
			
			URI predicate = mValueFactory.createURI(prop.getIRI().toURI().toString());
			Resource subject = subj.isAnonymous() ? mValueFactory.createBNode(subj.toString()) : mValueFactory.createURI(subj.getIRI().toURI().toString());
			Value object = null;
			
			if (obj.isLiteral()) {
				RDFLiteralNode literal = (RDFLiteralNode) obj;
				
				object = literal.isTyped() 	? mValueFactory.createLiteral(literal.getLiteral(), mValueFactory.createURI(literal.getDatatype().toString()))
											: mValueFactory.createLiteral(literal.getLiteral());
			}
			else {
				if (obj.isAnonymous()) {
					object =  mValueFactory.createBNode(obj.toString());
				}
				else {
					object =  mValueFactory.createURI(obj.getIRI().toURI().toString());
				}
			}
			
			try {
				mConnection.add(subject, predicate, object, mContext);
			} catch (RepositoryException e) {
				mError = e;
			}
			
		} catch (IllegalArgumentException e1) {
			// TODO Log it
		}
	}
}
